package com.bearsadmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bearsadmin.common.BusinessException;
import com.bearsadmin.dto.*;
import com.bearsadmin.entity.User;
import com.bearsadmin.mapper.UserMapper;
import com.bearsadmin.service.FileService;
import com.bearsadmin.service.UserService;
import com.bearsadmin.util.JwtUtil;
import com.bearsadmin.util.PasswordUtil;
import com.bearsadmin.vo.UserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 *
 * @author Bears Admin
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final FileService fileService;

    @Override
    public String login(LoginDTO loginDTO) {
        // 根据用户名查询用户
        User user = getUserByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new BusinessException("用户名或密码错误");
        }

        // 验证密码
        if (!PasswordUtil.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new BusinessException("用户已被禁用");
        }

        // 生成JWT token
        return JwtUtil.generateToken(user.getId(), user.getUsername());
    }

    @Override
    public UserVO register(RegisterDTO registerDTO) {
        // 验证密码一致性
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            throw new BusinessException("两次输入的密码不一致");
        }

        // 检查用户名是否存在
        User existUser = getUserByUsername(registerDTO.getUsername());
        if (existUser != null) {
            throw new BusinessException("用户名已存在");
        }

        // 检查邮箱是否存在
        if (StringUtils.hasText(registerDTO.getEmail())) {
            LambdaQueryWrapper<User> emailQuery = new LambdaQueryWrapper<>();
            emailQuery.eq(User::getEmail, registerDTO.getEmail());
            if (this.count(emailQuery) > 0) {
                throw new BusinessException("邮箱已被使用");
            }
        }

        // 检查手机号是否存在
        if (StringUtils.hasText(registerDTO.getPhone())) {
            LambdaQueryWrapper<User> phoneQuery = new LambdaQueryWrapper<>();
            phoneQuery.eq(User::getPhone, registerDTO.getPhone());
            if (this.count(phoneQuery) > 0) {
                throw new BusinessException("手机号已被使用");
            }
        }

        // 创建新用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(PasswordUtil.encode(registerDTO.getPassword()));
        user.setEmail(registerDTO.getEmail());
        user.setPhone(registerDTO.getPhone());
        user.setRole(1); // 默认普通用户
        user.setStatus(1); // 默认正常状态
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        // 保存用户
        this.save(user);

        // 转换为VO并返回
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public UserVO getUserById(Long id) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public UserVO updateUser(Long id, UserUpdateDTO userUpdateDTO) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查邮箱是否被其他用户使用
        if (StringUtils.hasText(userUpdateDTO.getEmail()) && !userUpdateDTO.getEmail().equals(user.getEmail())) {
            LambdaQueryWrapper<User> emailQuery = new LambdaQueryWrapper<>();
            emailQuery.eq(User::getEmail, userUpdateDTO.getEmail())
                    .ne(User::getId, id);
            if (this.count(emailQuery) > 0) {
                throw new BusinessException("邮箱已被其他用户使用");
            }
        }

        // 检查手机号是否被其他用户使用
        if (StringUtils.hasText(userUpdateDTO.getPhone()) && !userUpdateDTO.getPhone().equals(user.getPhone())) {
            LambdaQueryWrapper<User> phoneQuery = new LambdaQueryWrapper<>();
            phoneQuery.eq(User::getPhone, userUpdateDTO.getPhone())
                    .ne(User::getId, id);
            if (this.count(phoneQuery) > 0) {
                throw new BusinessException("手机号已被其他用户使用");
            }
        }

        // 更新用户信息
        if (StringUtils.hasText(userUpdateDTO.getEmail())) {
            user.setEmail(userUpdateDTO.getEmail());
        }
        if (StringUtils.hasText(userUpdateDTO.getPhone())) {
            user.setPhone(userUpdateDTO.getPhone());
        }
        if (userUpdateDTO.getGender() != null) {
            user.setGender(userUpdateDTO.getGender());
        }
        if (userUpdateDTO.getBirthday() != null) {
            user.setBirthday(userUpdateDTO.getBirthday());
        }
        if (StringUtils.hasText(userUpdateDTO.getRemark())) {
            user.setRemark(userUpdateDTO.getRemark());
        }
        user.setUpdatedAt(LocalDateTime.now());
        this.updateById(user);

        // 返回更新后的用户信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public User getUserByUsername(String username) {
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getUsername, username);
        return this.getOne(query);
    }

    @Override
    public UserVO uploadAvatar(Long id, MultipartFile file) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 删除旧头像
        if (StringUtils.hasText(user.getAvatar())) {
            fileService.deleteFile(user.getAvatar());
        }

        // 上传新头像
        String avatarUrl = fileService.uploadAvatar(file, id);

        // 更新用户头像信息
        user.setAvatar(avatarUrl);
        user.setUpdatedAt(LocalDateTime.now());
        this.updateById(user);

        log.info("用户 {} 头像更新成功: {}", id, avatarUrl);

        // 返回更新后的用户信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    // ================ 用户管理功能 ================

    @Override
    public IPage<UserVO> pageUsers(UserQueryDTO queryDTO) {
        // 创建分页对象
        Page<User> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());

        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 用户名模糊查询
        if (StringUtils.hasText(queryDTO.getUsername())) {
            queryWrapper.like(User::getUsername, queryDTO.getUsername());
        }

        // 邮箱模糊查询
        if (StringUtils.hasText(queryDTO.getEmail())) {
            queryWrapper.like(User::getEmail, queryDTO.getEmail());
        }

        // 手机号模糊查询
        if (StringUtils.hasText(queryDTO.getPhone())) {
            queryWrapper.like(User::getPhone, queryDTO.getPhone());
        }

        // 角色精确查询
        if (queryDTO.getRole() != null) {
            queryWrapper.eq(User::getRole, queryDTO.getRole());
        }

        // 状态精确查询
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(User::getStatus, queryDTO.getStatus());
        }

        // 性别精确查询
        if (queryDTO.getGender() != null) {
            queryWrapper.eq(User::getGender, queryDTO.getGender());
        }

        // 创建时间范围查询
        if (StringUtils.hasText(queryDTO.getCreatedStart())) {
            queryWrapper.ge(User::getCreatedAt, LocalDateTime.parse(queryDTO.getCreatedStart() + " 00:00:00",
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }
        if (StringUtils.hasText(queryDTO.getCreatedEnd())) {
            queryWrapper.le(User::getCreatedAt, LocalDateTime.parse(queryDTO.getCreatedEnd() + " 23:59:59",
                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }

        // 按创建时间倒序排列
        queryWrapper.orderByDesc(User::getCreatedAt);

        // 执行分页查询
        IPage<User> userPage = this.page(page, queryWrapper);

        // 转换为UserVO
        IPage<UserVO> userVOPage = userPage.convert(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        });

        return userVOPage;
    }

    @Override
    public UserVO createUser(UserCreateDTO createDTO) {
        // 检查用户名是否存在
        User existUser = getUserByUsername(createDTO.getUsername());
        if (existUser != null) {
            throw new BusinessException("用户名已存在");
        }

        // 检查邮箱是否存在
        if (StringUtils.hasText(createDTO.getEmail())) {
            LambdaQueryWrapper<User> emailQuery = new LambdaQueryWrapper<>();
            emailQuery.eq(User::getEmail, createDTO.getEmail());
            if (this.count(emailQuery) > 0) {
                throw new BusinessException("邮箱已被使用");
            }
        }

        // 检查手机号是否存在
        if (StringUtils.hasText(createDTO.getPhone())) {
            LambdaQueryWrapper<User> phoneQuery = new LambdaQueryWrapper<>();
            phoneQuery.eq(User::getPhone, createDTO.getPhone());
            if (this.count(phoneQuery) > 0) {
                throw new BusinessException("手机号已被使用");
            }
        }

        // 创建新用户
        User user = new User();
        BeanUtils.copyProperties(createDTO, user);
        user.setPassword(PasswordUtil.encode(createDTO.getPassword()));
        user.setCreatedAt(LocalDateTime.now());
        user.setUpdatedAt(LocalDateTime.now());

        // 保存用户
        this.save(user);

        log.info("管理员创建用户成功: {}", user.getUsername());

        // 转换为VO并返回
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public UserVO manageUser(Long id, UserManageDTO manageDTO) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 检查邮箱是否被其他用户使用
        if (StringUtils.hasText(manageDTO.getEmail()) && !manageDTO.getEmail().equals(user.getEmail())) {
            LambdaQueryWrapper<User> emailQuery = new LambdaQueryWrapper<>();
            emailQuery.eq(User::getEmail, manageDTO.getEmail())
                    .ne(User::getId, id);
            if (this.count(emailQuery) > 0) {
                throw new BusinessException("邮箱已被其他用户使用");
            }
        }

        // 检查手机号是否被其他用户使用
        if (StringUtils.hasText(manageDTO.getPhone()) && !manageDTO.getPhone().equals(user.getPhone())) {
            LambdaQueryWrapper<User> phoneQuery = new LambdaQueryWrapper<>();
            phoneQuery.eq(User::getPhone, manageDTO.getPhone())
                    .ne(User::getId, id);
            if (this.count(phoneQuery) > 0) {
                throw new BusinessException("手机号已被其他用户使用");
            }
        }

        // 更新用户信息
        if (StringUtils.hasText(manageDTO.getEmail())) {
            user.setEmail(manageDTO.getEmail());
        }
        if (StringUtils.hasText(manageDTO.getPhone())) {
            user.setPhone(manageDTO.getPhone());
        }
        if (manageDTO.getRole() != null) {
            user.setRole(manageDTO.getRole());
        }
        if (manageDTO.getStatus() != null) {
            user.setStatus(manageDTO.getStatus());
        }
        if (manageDTO.getGender() != null) {
            user.setGender(manageDTO.getGender());
        }
        if (manageDTO.getBirthday() != null) {
            user.setBirthday(manageDTO.getBirthday());
        }
        if (StringUtils.hasText(manageDTO.getRemark())) {
            user.setRemark(manageDTO.getRemark());
        }
        user.setUpdatedAt(LocalDateTime.now());
        this.updateById(user);

        log.info("管理员更新用户 {} 信息成功", user.getUsername());

        // 返回更新后的用户信息
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public boolean deleteUser(Long id) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 删除用户头像文件
        if (StringUtils.hasText(user.getAvatar())) {
            fileService.deleteFile(user.getAvatar());
        }

        // 删除用户记录
        boolean result = this.removeById(id);

        if (result) {
            log.info("管理员删除用户成功: {}", user.getUsername());
        }

        return result;
    }

    @Override
    public boolean batchDeleteUsers(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new BusinessException("用户ID列表不能为空");
        }

        // 查询要删除的用户
        List<User> users = this.listByIds(ids);

        // 删除用户头像文件
        users.forEach(user -> {
            if (StringUtils.hasText(user.getAvatar())) {
                fileService.deleteFile(user.getAvatar());
            }
        });

        // 批量删除用户记录
        boolean result = this.removeByIds(ids);

        if (result) {
            List<String> usernames = users.stream()
                    .map(User::getUsername)
                    .collect(Collectors.toList());
            log.info("管理员批量删除用户成功: {}", usernames);
        }

        return result;
    }

    @Override
    public String resetPassword(Long id) {
        User user = this.getById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 生成6位随机密码
        String newPassword = generateRandomPassword();

        // 更新密码
        user.setPassword(PasswordUtil.encode(newPassword));
        user.setUpdatedAt(LocalDateTime.now());
        this.updateById(user);

        log.info("管理员重置用户 {} 密码成功", user.getUsername());

        return newPassword;
    }

    /**
     * 生成随机密码
     *
     * @return 随机密码
     */
    private String generateRandomPassword() {
        String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder password = new StringBuilder();

        for (int i = 0; i < 6; i++) {
            password.append(chars.charAt(random.nextInt(chars.length())));
        }

        return password.toString();
    }
}